package com.mzwise.tunnel.wx.v3;

import com.alibaba.fastjson.JSON;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


public class WxV3Client {

    public WxV3Client(String merchantId, String serialNo, String privateKeyFilePath, String wechatpayCertificatePath) {
        try {
            this.merchantId = merchantId;
            this.serialNo = serialNo;
            this.privateKeyFilePath = privateKeyFilePath;
            this.wechatpayCertificatePath = wechatpayCertificatePath;
            WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create()
                    .withMerchant(merchantId, serialNo, PemUtil.loadPrivateKey(new FileInputStream(privateKeyFilePath)));
            List<X509Certificate> certs = new ArrayList<>();
            certs.add(PemUtil.loadCertificate(new FileInputStream(wechatpayCertificatePath)));
            builder.withWechatpay(certs);
            CloseableHttpClient httpClient = builder.build();
            this.setHttp(httpClient);
        } catch (FileNotFoundException e) {
            System.out.println("tunnel:v3 client init fail");
            e.printStackTrace();
        }
    }

    private CloseableHttpClient http;

    private String baseUrl;

    private String appid;

    private String merchantId;

    private String privateKeyFilePath;

    private String serialNo;

    private String wxSerialNo;

    private String wechatpayCertificatePath;

    private String privateKey;

    public CloseableHttpClient getHttp() {
        return http;
    }

    public void setHttp(CloseableHttpClient http) {
        this.http = http;
    }

    public String getBaseUrl() {
        return baseUrl;
    }

    public void setBaseUrl(String baseUrl) {
        this.baseUrl = baseUrl;
    }

    public String getAppid() {
        return appid;
    }

    public void setAppid(String appid) {
        this.appid = appid;
    }

    public String getMerchantId() {
        return merchantId;
    }

    public void setMerchantId(String merchantId) {
        this.merchantId = merchantId;
    }

    public String getPrivateKeyFilePath() {
        return privateKeyFilePath;
    }

    public void setPrivateKeyFilePath(String privateKeyFilePath) {
        this.privateKeyFilePath = privateKeyFilePath;
    }

    public String getSerialNo() {
        return serialNo;
    }

    public void setSerialNo(String serialNo) {
        this.serialNo = serialNo;
    }

    public String getWxSerialNo() {
        return wxSerialNo;
    }

    public void setWxSerialNo(String wxSerialNo) {
        this.wxSerialNo = wxSerialNo;
    }

    public String getWechatpayCertificatePath() {
        return wechatpayCertificatePath;
    }

    public void setWechatpayCertificatePath(String wechatpayCertificatePath) {
        this.wechatpayCertificatePath = wechatpayCertificatePath;
    }

    public String getPrivateKey() {
        return privateKey;
    }

    public void setPrivateKey(String privateKey) {
        this.privateKey = privateKey;
    }

    public WxV3Response execute(HttpPost httpPost) throws IOException {
        return execute(httpPost, false);
    }

    public WxV3Response execute(HttpPost httpPost, Boolean withCert) throws IOException {
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-Type", "application/json");
        if (withCert) {
            httpPost.addHeader("Wechatpay-Serial", wxSerialNo);
        }
        CloseableHttpResponse response = http.execute(httpPost);
        int statusCode = response.getStatusLine().getStatusCode();
        String body = EntityUtils.toString(response.getEntity());
        WxV3Response wxV3Response = new WxV3Response();
        if (statusCode == 200) {
            wxV3Response.setOk(true);
        } else {
            System.out.println("error:" + body);
            wxV3Response.setOk(false);
        }
        Map<String, String> maps = (Map<String, String>) JSON.parse(body);
        wxV3Response.setBody(maps);
        return wxV3Response;
    }

    public WxV3Response execute(HttpGet httpGet) throws IOException {
        return execute(httpGet, false);
    }

    public WxV3Response execute(HttpGet httpGet, Boolean withCert) throws IOException {
        httpGet.addHeader("Accept", "application/json");
        httpGet.addHeader("Content-Type", "application/json");
        if (withCert) {
            httpGet.addHeader("Wechatpay-Serial", wxSerialNo);
        }
        CloseableHttpResponse response = http.execute(httpGet);
        int statusCode = response.getStatusLine().getStatusCode();
        String body = EntityUtils.toString(response.getEntity());
        WxV3Response wxV3Response = new WxV3Response();
        if (statusCode == 200) {
            wxV3Response.setOk(true);
        } else {
            System.out.println("error:" + body);
            wxV3Response.setOk(false);
        }
        Map<String, String> maps = (Map<String, String>) JSON.parse(body);
        wxV3Response.setBody(maps);
        return wxV3Response;
    }
}
